#!/usr/local/bin/python3
import comtrade
import os
import os.path as op
import sys

helpinfo = "\ncomtrade can convert comtrade files to pic file or csv data file. \
The tool can also show the wave figure. Addionally, \
It can convert multiple files in the dir. And it can diff two or more files to show \
data property!\n\n\
Usage:\n\
  comtrade subcommand [options [args]] [file/dir]\n\n\
subcommand:\n\
  convert: convert the comtrade data to pic file or csv file;\n\
  diff: diff two or more wave data with speciied mode;\n\
  help: print comtrade help info or print specified sub-command help info;\n\
  show: show a wave figure for specify comtrade cfg file or dat file;\n\
\n\
  get help info of sub command:\n\
    comtrade help [subcommand]\n"

converthelpinfo = "\nconvert command can convert the specified comtrade files to \
specified format file.\n\
options:\n\
  -h: print the help infomation\n\
  -c: specify channel type to plot\n\
  -f: set the file format convert to, with args specifying file format\n\n\
args:\n\
  channel type: all, analog, digital\n\
  format: pdf, png, eps, svg, ps, csv\n\n\
file/dir:\n\
  file: specify a couple of comtrade files\n\
  dir: specify a direction, convert the files in the direction\n\n\
Default:\n\
  default format is pdf.\n\n\
Example:\n\
  comtrade convert -f png xxx.cfg\n"

showhelpinfo = "\nshow command can show wave figure of the specified comtrade files.\n\
options:\n\
  -h: print the help infomation\n\
  -c: specify channel type to plot\n\
  -f: set the file format convert to, with args specifying file format\n\n\
args:\n\
  channel type: all, analog, digital\n\
  format: pdf, png, eps, svg, ps, csv\n\n\
file/dir:\n\
  file: specify a couple of comtrade files\n\
  dir: specify a direction, convert the files in the direction\n\n\
Default:\n\
  default format is pdf.\n\n\
Example:\n\
  comtrade show -f png xxx.cfg\n"

diffhelpinfo = "diff command"

subcommandList = ['convert', 'show', 'diff', 'help']
formatList = ['png', 'pdf', 'ps', 'svg', 'csv', 'eps']
chtypeList = ['all', 'analog', 'digital']
helpinfoList = {}

def printinfo(info):
    print(info)

def inithelpinfo():
    helpinfoList = {}
    helpinfoList['convert'] = converthelpinfo
    helpinfoList['show'] = showhelpinfo
    helpinfoList['diff'] = diffhelpinfo
    helpinfoList['help'] = helpinfo
    return helpinfoList
        
def initargs():
    """
    init the args dictionary
    """
    argdict = dict()
    argdict['subcommand'] = 'convert'
    argdict['help'] = ''
    argdict['-h'] = False
    argdict['-s'] = False
    argdict['-c'] = 'analog'
    argdict['-f'] = 'pdf'
    argdict['object'] = 'file'
    argdict['path'] = ''
    return argdict

def parseargs(argdict, args=sys.argv):
    """
    parse the sys.argv and get valid args
    1. argdict: the args dictionary
    2. args: sys.argv
    """
    length = len(args)
    if length == 1:
        printinfo(helpinfoList['help'])
        sys.exit(0)
    if not args[1] in subcommandList:
        printinfo(helpinfoList['help'])
        sys.exit(1)
    else:
        argdict['subcommand'] = args[1]
    if argdict['subcommand'] == 'help':
        if length == 2:
            printinfo(helpinfoList['help'])
            sys.exit(0)
        if args[2] in subcommandList:
            printinfo(helpinfoList[args[2]])
            sys.exit(0)
        else:
            print("\nspecified subcommand is not supported!\n  More info: comtrade help\n")
            sys.exit(1)
    else:
        if length == 2:
            printinfo(helpinfoList[argdict['subcommand']])
            sys.exit(1)
    for i in range(2, length):
        if args[i][0] == '-':
            if len(args[i]) == 2:
                if args[i] == '-h':
                    argdict['-h'] = True
                elif args[i] == '-c':
                    if i >= length - 1:
                        print("the option -c has no specified format, please check help info: comtrade -h")
                        sys.exit(1)
                    else:
                        if args[i+1] in chtypeList:
                            argdict['-c'] = args[i+1]
                        else:
                            print('the channel type is not supported, you can specify: all, analog or digital!')
                            sys.exit(1)
                elif args[i] == '-f':
                    if i >= length - 1:
                        print("the option -f has no specified format, please check help info: comtrade -h")
                        sys.exit(1)
                    else:
                        if args[i+1] in formatList:
                            argdict['-f'] = args[i+1]
                        else:
                            print('the format is not supported, you can specify: png, pdf, eps, ps, svg and csv')
                            sys.exit(1)
                else:
                    print('unknown option: %s, please check help info: comtrade -h' % args[i])
                    sys.exit(1)
            else:
                print('the option %s is invalid! Get help info: comtrade -h' % args)
                sys.exit(1)
    if args[-1][0] == '-':
        if argdict['-h'] == False:
            print('have no valid file or direction, please check if specify a file or direction!\nmore info: comtrade -h')
            sys.exit(1)
        else:
            printinfo(helpinfoList[argdict['subcommand']])
            sys.exit(0)
    fileordir = op.abspath(args[-1])
    if op.isdir(fileordir):
        argdict['object'] = 'dir'
    else:
        argdict['object'] = 'file'
    if not op.exists(fileordir):
        print('\nThe file doesn\'t exist, please select a valid contrade configuration file!\n')
        sys.exit(1)
    else:
        argdict['path'] = fileordir
    return argdict

def parsewave(wavefile, chtype='analog'):
    """
    parse the cfg file
    """
    parser = comtrade.ComtradeParser(wavefile)
    if parser.result == 'parsed':
        parser.plot(chtype)
    return parser

def scancfgfile(dirpath):
    """
    list the files in dirpath, and get cfg files list
    """
    cfgfiles = list()
    files = os.listdir(dirpath)
    for each in files:
        if '.cfg' in each:
            cfgfiles.append(each)
    return cfgfiles

helpinfoList = inithelpinfo()
argdict = initargs()
argdict = parseargs(argdict, sys.argv)

if argdict['-h'] == True:
    printinfo(helpinfoList[argdict['subcommand']])
    sys.exit(0)

if argdict['subcommand'] == 'convert':
    if argdict['object'] == 'file':
        print('parsing the file: %s ...' % argdict['path'])
        parser = parsewave(argdict['path'], argdict['-c'])
        if parser.result == 'parsed':
            print('parsed! Export the %s file of channel-%s ...' % (argdict['-f'], argdict['-c']))
            parser.savefig(argdict['-f'])
            print('Done!')
        else:
            print('\nParse [%s] failed! Error: %s\n' % (argdict['path'], parser.result))
    else:
        cfgfiles = scancfgfile(argdict['path'])
        if len(cfgfiles) == 0:
            print("%s has no comtrade file!" % argdict['path'])
            sys.exit(0)
        print("parsing the %d file:" % len(cfgfiles))
        for cfgfile in cfgfiles:
            print("  %s ..." % cfgfile)
            parser = parsewave(cfgfile, argdict['-c'])
            if parser.result == 'parsed':
                print('    parsed! Export the %s file of %s channel ...' % (argdict['-f'], argdict['-c']))
                parser.savefig(argdict['-f'])
            else:
                print('\nParse [%s] failed! Error: %s\n' % (argdict['path'], parser.result))
        print('Done!')
elif argdict['subcommand'] == 'show':
    if argdict['object'] == 'file':
        parser = parsewave(argdict['path'], argdict['-c'])
        parser.show()
    else:
        print("show command only support comtrade file not direction!")

